package com.mini.controller;

import com.mini.client.MiniExcelClient;
import com.mini.client.cache.CacheMnsClient;
import com.mini.common.annotation.AutoLog;
import com.mini.common.config.WebAppConfigurer;
import com.mini.constant.KanbanDimension;
import com.mini.es.service.EsBusinessStudentBigLessonXcxService;
import com.mini.mysql.service.MnsService;
import com.mini.vo.BusinessResult;
import com.mini.vo.KanbanDataFormatVO;
import com.mini.vo.KanbanPageCondition;
import com.mini.vo.KanbanResultVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.common.StopWatch;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.Comparator;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/kanban")
@Slf4j
@Api(tags = "数据看板相关")
public class KanbanController {

    @Autowired
    private CacheMnsClient cacheMnsClient;
    @Autowired
    private MiniExcelClient miniExcelClient;

    @ApiOperation(value = "数据看板分页列表")
    @AutoLog
    @PostMapping(value = "/page")
    public BusinessResult<KanbanResultVO<KanbanDataFormatVO>> page(@ApiParam(value = "token", required = true) @RequestHeader String Authorization,
                                                                   @RequestBody KanbanPageCondition param) {
        param.setLoginUserToken(Authorization);
        if (KanbanDimension.dimension_class.name().equals(param.getDimension())) {
            BusinessResult<KanbanResultVO<KanbanDataFormatVO>> page = miniExcelClient.page(param.getLoginUserToken(), param);
            return page;
        }
        StopWatch stopWatch = new StopWatch();
        stopWatch.start("search");
        List<KanbanDataFormatVO> rows = esBusinessStudentBigLessonXcxService.summaryDataByUser(param);
        stopWatch.stop();
        stopWatch.start("fenzu");
        //结果处理-如果查询结果维度为组，进行分组处理
        if (KanbanDimension.dimension_org_group.name().equals(param.getDimension())) {
            rows = rows.stream()
                    .collect(Collectors.groupingBy(KanbanDataFormatVO::getGroupId))
                    .entrySet().stream().map(m -> {
                        KanbanDataFormatVO groupSummary = totalSummary(m.getValue());
                        groupSummary.setGroupId(m.getKey());
                        if (Objects.nonNull(m.getKey())) {
                            String groupName = cacheMnsClient.getDeptFullName(WebAppConfigurer.getSign(), m.getKey());
                            if (StringUtils.isNotBlank(groupName)) {
                                String[] split = groupName.split("-");
                                if (split.length == 5) {
                                    groupSummary.setSkuName(split[1]);
                                    groupSummary.setStudioName(split[2]);
                                    groupSummary.setDeptName(split[3]);
                                    groupSummary.setGroupName(split[4]);
                                }
                            }
                        }
                        return groupSummary;
                    }).sorted(Comparator.comparing(KanbanDataFormatVO::getGroupId)).collect(Collectors.toList());
        } else if (KanbanDimension.dimension_teacher.name().equals(param.getDimension())) {
            rows.forEach(m -> {
                String groupName = cacheMnsClient.getDeptFullName(WebAppConfigurer.getSign(), m.getGroupId());
                if (StringUtils.isNotBlank(groupName)) {
                    String[] split = groupName.split("-");
                    if (split.length == 5) {
                        m.setSkuName(split[1]);
                        m.setStudioName(split[2]);
                        m.setDeptName(split[3]);
                        m.setGroupName(split[4]);
                    }
                }
            });
        } else if (KanbanDimension.dimension_org_dept.name().equals(param.getDimension())) {
            rows = rows.stream()
                    .collect(Collectors.groupingBy(KanbanDataFormatVO::getDeptId))
                    .entrySet().stream().map(m -> {
                        KanbanDataFormatVO groupSummary = totalSummary(m.getValue());
                        groupSummary.setDeptId(m.getKey());
                        if (Objects.nonNull(m.getKey())) {
                            String groupName = cacheMnsClient.getDeptFullName(WebAppConfigurer.getSign(), m.getKey());
                            if (StringUtils.isNotBlank(groupName)) {
                                String[] split = groupName.split("-");
                                if (split.length == 4) {
                                    groupSummary.setSkuName(split[1]);
                                    groupSummary.setStudioName(split[2]);
                                    groupSummary.setDeptName(split[3]);
                                }
                            }
                        }
                        return groupSummary;
                    }).sorted(Comparator.comparing(KanbanDataFormatVO::getDeptId)).collect(Collectors.toList());
        } else if (KanbanDimension.dimension_org_studio.name().equals(param.getDimension())) {
            rows = rows.stream()
                    .collect(Collectors.groupingBy(KanbanDataFormatVO::getStudioId))
                    .entrySet().stream().map(m -> {
                        KanbanDataFormatVO groupSummary = totalSummary(m.getValue());
                        groupSummary.setStudioId(m.getKey());
                        if (Objects.nonNull(m.getKey())) {
                            String groupName = cacheMnsClient.getDeptFullName(WebAppConfigurer.getSign(), m.getKey());
                            if (StringUtils.isNotBlank(groupName)) {
                                String[] split = groupName.split("-");
                                if (split.length == 3) {
                                    groupSummary.setSkuName(split[1]);
                                    groupSummary.setStudioName(split[2]);
                                }
                            }
//                            groupSummary.setStudioName(groupName);
                        }
                        return groupSummary;
                    }).sorted(Comparator.comparing(KanbanDataFormatVO::getStudioId)).collect(Collectors.toList());
        } else if (KanbanDimension.dimension_org_sku.name().equals(param.getDimension())) {
            rows = rows.stream()
                    .collect(Collectors.groupingBy(KanbanDataFormatVO::getSkuId))
                    .entrySet().stream().map(m -> {
                        KanbanDataFormatVO groupSummary = totalSummary(m.getValue());
                        groupSummary.setSkuId(m.getKey());
                        if (Objects.nonNull(m.getKey())) {
                            String groupName = cacheMnsClient.getDeptFullName(WebAppConfigurer.getSign(), m.getKey());
                            if (StringUtils.isNotBlank(groupName)) {
                                String[] split = groupName.split("-");
                                if (split.length == 2) {
                                    groupSummary.setSkuName(split[1]);
                                }
                            }
                        }
                        return groupSummary;
                    }).sorted(Comparator.comparing(KanbanDataFormatVO::getSkuId)).collect(Collectors.toList());
        } else if (KanbanDimension.dimension_class.name().equals(param.getDimension())) {

        }
        stopWatch.stop();
        stopWatch.start("total");

        KanbanDataFormatVO totalRecord = totalSummary(rows);

        totalRecord.fillData();
        KanbanResultVO<KanbanDataFormatVO> result = new KanbanResultVO<>();
        //结果处理-ES中分组查询不能分页，这里手动分页


        KanbanDataFormatVO unRef = null;
        if (KanbanDimension.dimension_org_group.name().equals(param.getDimension())) {
            unRef = rows.stream().filter(r -> r.getGroupId() == 0L).findFirst().orElse(null);
            unRef.setGroupName("未关联数据");
            totalRecord.setGroupName("总计");
            rows = rows.stream().filter(r -> r.getGroupId() != 0L).collect(Collectors.toList());
        } else if (KanbanDimension.dimension_teacher.name().equals(param.getDimension())) {
            unRef = rows.stream().filter(r -> r.getTeacherId() == 0L).findFirst().orElse(null);
            unRef.setTeacherName("未关联数据");
            totalRecord.setTeacherName("总计");
            rows = rows.stream().filter(r -> r.getTeacherId() != 0L).collect(Collectors.toList());
        } else if (KanbanDimension.dimension_org_dept.name().equals(param.getDimension())) {
            unRef = rows.stream().filter(r -> r.getDeptId() == 0L).findFirst().orElse(null);
            unRef.setDeptName("未关联数据");
            totalRecord.setDeptName("总计");
            rows = rows.stream().filter(r -> r.getDeptId() != 0L).collect(Collectors.toList());
        } else if (KanbanDimension.dimension_org_studio.name().equals(param.getDimension())) {
            unRef = rows.stream().filter(r -> r.getStudioId() == 0L).findFirst().orElse(null);
            unRef.setStudioName("未关联数据");
            totalRecord.setStudioName("总计");
            rows = rows.stream().filter(r -> r.getStudioId() != 0L).collect(Collectors.toList());
        } else if (KanbanDimension.dimension_org_sku.name().equals(param.getDimension())) {
            unRef = rows.stream().filter(r -> r.getSkuId() == 0L).findFirst().orElse(null);
            unRef.setSkuName("未关联数据");
            totalRecord.setSkuName("总计");
            rows = rows.stream().filter(r -> r.getSkuId() != 0L).collect(Collectors.toList());
        } else if (KanbanDimension.dimension_class.name().equals(param.getDimension())) {

        }
        stopWatch.stop();
        stopWatch.start("row");
        int skip = param.getPageSize() * (param.getPageNumber() - 1);
        result.setTotal(rows.size());
        rows = rows.stream().skip(skip).limit(param.getPageSize()).collect(Collectors.toList());
        rows.forEach(KanbanDataFormatVO::fillData);
        result.setUnRefRecord(unRef);
        result.setRows(rows);
        result.setTotalRecord(totalRecord);
        stopWatch.stop();
        log.info("{}", stopWatch.prettyPrint());
        return BusinessResult.createSuccessInstance(result);
    }

    /**
     * 统计求和
     */
    public static KanbanDataFormatVO totalSummary(List<KanbanDataFormatVO> collect) {
        return CollectionUtils.isEmpty(collect) ? null : KanbanDataFormatVO.builder()
                .orderCount(collect.stream().map(KanbanDataFormatVO::getOrderCount).filter(Objects::nonNull).reduce(Long::sum).orElse(0L))
                .addWechatGroupStateCount(collect.stream().map(KanbanDataFormatVO::getAddWechatGroupStateCount).filter(Objects::nonNull).reduce(Long::sum).orElse(0L))
                .admissionTestStateCount(collect.stream().map(KanbanDataFormatVO::getAdmissionTestStateCount).filter(Objects::nonNull).reduce(Long::sum).orElse(0L))
                .attnFullDuration(collect.stream().map(KanbanDataFormatVO::getAttnFullDuration).filter(Objects::nonNull).reduce(Long::sum).orElse(0L))
                .attnAttnCount(collect.stream().map(KanbanDataFormatVO::getAttnAttnCount).filter(Objects::nonNull).reduce(Long::sum).orElse(0L))
                .attnFullLiveDuration(collect.stream().map(KanbanDataFormatVO::getAttnFullLiveDuration).filter(Objects::nonNull).reduce(Long::sum).orElse(0L))
                .attnTotalDuration(collect.stream().map(KanbanDataFormatVO::getAttnTotalDuration).filter(Objects::nonNull).reduce(Long::sum).orElse(0L))
                .attnAttnVodCount(collect.stream().map(KanbanDataFormatVO::getAttnAttnVodCount).filter(Objects::nonNull).reduce(Long::sum).orElse(0L))
                .attnCourseCount(collect.stream().map(KanbanDataFormatVO::getAttnCourseCount).filter(Objects::nonNull).reduce(Long::sum).orElse(0L))
                .attnFinishCount(collect.stream().map(KanbanDataFormatVO::getAttnFinishCount).filter(Objects::nonNull).reduce(Long::sum).orElse(0L))
                .attnFinishLiveCount(collect.stream().map(KanbanDataFormatVO::getAttnFinishLiveCount).filter(Objects::nonNull).reduce(Long::sum).orElse(0L))
                .bigLessonCount(collect.stream().map(KanbanDataFormatVO::getBigLessonCount).filter(Objects::nonNull).reduce(Integer::sum).orElse(0))
                .bigLessonPriceTotal(collect.stream().map(KanbanDataFormatVO::getBigLessonPrice).filter(Objects::nonNull).reduce(Float::sum).orElse(null))
                .bigLessonDepositCount(collect.stream().map(KanbanDataFormatVO::getBigLessonDepositCount).filter(Objects::nonNull).reduce(Integer::sum).orElse(0))
                .bigLessonRefundFee(collect.stream().map(KanbanDataFormatVO::getBigLessonRefundFee).filter(Objects::nonNull).reduce(Float::sum).orElse(null))
                .attnAttnLiveCount(collect.stream().map(KanbanDataFormatVO::getAttnAttnLiveCount).filter(Objects::nonNull).reduce(Long::sum).orElse(0L))
                .followPublicCount(collect.stream().map(KanbanDataFormatVO::getFollowPublicCount).filter(Objects::nonNull).reduce(Long::sum).orElse(0L))
                .getCouponCount(collect.stream().map(KanbanDataFormatVO::getGetCouponCount).filter(Objects::nonNull).reduce(Long::sum).orElse(0L))
                .secBigLessonCount(collect.stream().map(KanbanDataFormatVO::getSecBigLessonCount).filter(Objects::nonNull).reduce(Integer::sum).orElse(0))
                .secBigLessonPrice(collect.stream().map(KanbanDataFormatVO::getSecBigLessonPrice).filter(Objects::nonNull).reduce(Float::sum).orElse(null))
                .secBigLessonDepositCount(collect.stream().map(KanbanDataFormatVO::getSecBigLessonDepositCount).filter(Objects::nonNull).reduce(Integer::sum).orElse(0))
                .secBigLessonPriceTotal(collect.stream().map(KanbanDataFormatVO::getSecBigLessonPriceTotal).filter(Objects::nonNull).reduce(Float::sum).orElse(null))
                .secXcxCount(collect.stream().map(KanbanDataFormatVO::getSecXcxCount).filter(Objects::nonNull).reduce(Integer::sum).orElse(0))
                .secXcxFee(collect.stream().map(KanbanDataFormatVO::getSecXcxFee).filter(Objects::nonNull).reduce(Float::sum).orElse(null))
                .secXcxRefundFee(collect.stream().map(KanbanDataFormatVO::getXcxRefundFee).filter(Objects::nonNull).reduce(Float::sum).orElse(null))
                .secYouzanCount(collect.stream().map(KanbanDataFormatVO::getYouzanCount).filter(Objects::nonNull).reduce(Integer::sum).orElse(0))
                .secBigLessonRefundFee(collect.stream().map(KanbanDataFormatVO::getSecBigLessonRefundFee).filter(Objects::nonNull).reduce(Float::sum).orElse(null))
                .secYouzanFee(collect.stream().map(KanbanDataFormatVO::getSecYouzanFee).filter(Objects::nonNull).reduce(Float::sum).orElse(null))
                .unPayZeroStateCount(collect.stream().map(KanbanDataFormatVO::getUnPayZeroStateCount).filter(Objects::nonNull).reduce(Long::sum).orElse(0L))
                .unRefBigLessonCount(collect.stream().map(KanbanDataFormatVO::getUnRefBigLessonCount).filter(Objects::nonNull).reduce(Integer::sum).orElse(0))
                .unRefBigLessonDepositCount(collect.stream().map(KanbanDataFormatVO::getUnRefBigLessonDepositCount).filter(Objects::nonNull).reduce(Integer::sum).orElse(0))
                .unRefBigLessonPrice(collect.stream().map(KanbanDataFormatVO::getUnRefBigLessonPrice).filter(Objects::nonNull).reduce(Float::sum).orElse(null))
                .unRefBigLessonPriceTotal(collect.stream().map(KanbanDataFormatVO::getUnRefBigLessonPriceTotal).filter(Objects::nonNull).reduce(Float::sum).orElse(null))
                .unRefYouzanCount(collect.stream().map(KanbanDataFormatVO::getUnRefYouzanCount).filter(Objects::nonNull).reduce(Integer::sum).orElse(0))
                .unRefXcxFee(collect.stream().map(KanbanDataFormatVO::getUnRefXcxFee).filter(Objects::nonNull).reduce(Float::sum).orElse(null))
                .unRefXcxCount(collect.stream().map(KanbanDataFormatVO::getUnRefXcxCount).filter(Objects::nonNull).reduce(Integer::sum).orElse(0))
                .unRefYouzanFee(collect.stream().map(KanbanDataFormatVO::getUnRefYouzanFee).filter(Objects::nonNull).reduce(Float::sum).orElse(null))
                .statesCount(collect.stream().map(KanbanDataFormatVO::getStatesCount).filter(Objects::nonNull).reduce(Long::sum).orElse(0L))
                .attnFullLiveDuration(collect.stream().map(KanbanDataFormatVO::getAttnFullLiveDuration).filter(Objects::nonNull).reduce(Long::sum).orElse(0L))
                .youzanFee(collect.stream().map(KanbanDataFormatVO::getYouzanFee).filter(Objects::nonNull).reduce(Float::sum).orElse(null))
                .youzanRefundFee(collect.stream().map(KanbanDataFormatVO::getYouzanRefundFee).filter(Objects::nonNull).reduce(Float::sum).orElse(null))
                .youzanCount(collect.stream().map(KanbanDataFormatVO::getYouzanCount).filter(Objects::nonNull).reduce(Integer::sum).orElse(0))
                .bigLessonPrice(collect.stream().map(KanbanDataFormatVO::getBigLessonPrice).filter(Objects::nonNull).reduce(Float::sum).orElse(null))
                .xcxFee(collect.stream().map(KanbanDataFormatVO::getXcxFee).filter(Objects::nonNull).reduce(Float::sum).orElse(null))
                .xcxRefundFee(collect.stream().map(KanbanDataFormatVO::getXcxRefundFee).filter(Objects::nonNull).reduce(Float::sum).orElse(null))
                .xcxCount(collect.stream().map(KanbanDataFormatVO::getXcxCount).filter(Objects::nonNull).reduce(Integer::sum).orElse(0))
                .build();
    }

    @Autowired
    private EsBusinessStudentBigLessonXcxService esBusinessStudentBigLessonXcxService;

}
